﻿/*
	Class Description: the main class of MiniDebugger library
	------------------------------------------------------------------------
	                          APACHE LICENSE
	------------------------------------------------------------------------
	Copyright 2010 Vu Thien Nguyen Phong
	
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at
	
	http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/
package com.minidebugger  {
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getTimer;
	import flash.system.System;

	public class MiniDebugger{
		// MiniDebugger's GUI is structured in multiple panels.
		// Each panel is in charged of a specific task. 
		// Tracing panel handles all trace commands of MiniDebugger
		private static var tracingPanel:TracingPanel;
		// FPSPanel monitors memory usage and framerate of flash
		private static var fpsPanel:FPSPanel;
		
		// before using MiniDebugger, you have to call functions
		// get..Panel() (eg: getTracingPanel()) to receive the panel
		// and add it to stage before using them. See sample to know more
		public static function getTracingPanel():TracingPanel{
			if (!tracingPanel)
				tracingPanel = new TracingPanel();
			return tracingPanel;	
		}
		
		public static function getFPSPanel():FPSPanel{
			if (!fpsPanel)
				fpsPanel = new FPSPanel();
				
			fpsPanel.x = 340;	
			fpsPanel.y = 20;
			return fpsPanel;	
		}
		
		//-------------------TRACING PANEL FUNCTIONS-------------------------
		// the main function of TracingPanel, call it to print out
		// anything you want on tracingPanel. Set showType = true if
		// you want to output type (Number,int,...) of s. Set showName = true
		// to show the instance name of Objects
		public static function trace(s:*,showInstanceName:Boolean=false,showType:Boolean = false):void{
			if (tracingPanel){ // only trace if debugPanel was created
				var className:String = getQualifiedClassName(s);
				var type:String = "";
				var varName:String = "";
				
				if (showType)
					type = " <font color=\"#23a2c6\">[type="+className+"]</font>";
					
				if (showInstanceName){
					if (className!="int"&&className!="uint"&&className!="Number"&&className!="String"&&className!="Boolean"&&className!="void"&&className!="Null"&&className!="Array")
						varName = " <font color=\"#23a2c6\">[name="+s.name+"]</font>";
				}
				
				tracingPanel.trace("::"+s+type+varName);
			}
		}
		
		// list all elements of a one dimensional array
		public static function traceArray(a:Array):void{
			if (tracingPanel){
				tracingPanel.trace("::<font color=\"#c830a2\">[Array length="+a.length+"]</font>");
				for(var i:int=0;i<a.length;i++)
					tracingPanel.trace(">>><font color=\"#c830a2\">Array["+i+"]</font> = "+a[i]);
			}
		}
		
		// list all elements of a two dimensional array
		public static function trace2DArray(a:Array):void{
			if (tracingPanel){
				tracingPanel.trace("::<font color=\"#c830a2\">[Array length="+a.length+"]</font>");
				var s:String = "";
				for(var i:int=0;i<a.length;i++){
					s += ">>><font color=\"#c830a2\">Array["+i+" length="+a[i].length+"]</font> "
					for(var j:int=0;j<a[i].length;j++){
						s +=a[i][j]+" ";
					}
					tracingPanel.trace(s);
					s = "";
				}
			}
		}
		
		public static function traceObject(obj:Object):void{
			if (tracingPanel){
				tracingPanel.trace("::<font color=\"#ea4707\">[Object name="+obj.name+"]</font>");
				for(var key:String in obj)
					tracingPanel.trace(">>><font color=\"#ea4707\">"+obj.name+"."+key+"</font> = "+obj[key]);
			}
		}
		
		public static function testFunction(testCaseName:String,func:Function,args:Array):void{
			tracingPanel.trace(">>><font color=\"#23a2c6\">"+testCaseName+" started</font>");
			var tick:int = getTimer();
			var mem:uint = System.totalMemory;
			
			if (args.length==0)
				func();
			else if (args.length==1)
				func(args[0]);
			else if (args.length==2)
				func(args[0],args[1]);
			else if (args.length==3)
				func(args[0],args[1],args[2]);
			else if (args.length==4)
				func(args[0],args[1],args[2],args[3]);
			else if (args.length==5)
				func(args[0],args[1],args[2],args[3],args[4]);
			else if (args.length==6)
				func(args[0],args[1],args[2],args[3],args[4],args[5]);
			else if (args.length==7)
				func(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
			else if (args.length==8)
				func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
			else if (args.length==9)
				func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);	
			else
				throw new Error("Error: You can test functions with maximum 9 parameters");
				
			tracingPanel.trace(">>><font color=\"#23a2c6\">"+testCaseName+"'s result:</font> <font color=\"#ea4707\">"+(getTimer()-tick)+" ms / "+((System.totalMemory-mem)/1024)+"Kb</font>");
		}
	}
}
